package com.learning.servlet2x.listener;


import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import java.util.Date;

/**
 * ClassName: ObjectAttributeListener
 * Description: 在线人数监听器：监听Session对象属性变化，监听Session 属性变化
 * 1、需要记录在线用户列表、总访问人数等
 * Date: 2014-12-10 22:25 【需求编号】
 *
 * @author Sam Sho
 * @version V1.0.0
 */
public class OnlineSessionListener implements HttpSessionListener, HttpSessionAttributeListener {

    /**
     * 监听 Session 创建
     *
     * @param sessionEvent
     */
    @Override
    public void sessionCreated(HttpSessionEvent sessionEvent) {

        HttpSession session = sessionEvent.getSession();

        // 将 session 放入 map
        OnlineConstants.SESSION_MAP.put(session.getId(), session);
        // 总访问人数++
        OnlineConstants.TOTAL_HISTORY_COUNT++;

        // 如果当前在线人数超过历史记录，则更新最大在线人数，并记录时间
        int sessionCount = OnlineConstants.SESSION_MAP.size();
        if (sessionCount > OnlineConstants.MAX_ONLINE_COUNT) {
            OnlineConstants.MAX_ONLINE_COUNT = sessionCount;
            OnlineConstants.MAX_ONLINE_COUNT_DATE = new Date();
        }
    }

    /**
     * 监听Session 销毁
     *
     * @param sessionEvent
     */
    @Override
    public void sessionDestroyed(HttpSessionEvent sessionEvent) {
        HttpSession session = sessionEvent.getSession();
        // 将session从map中移除
        OnlineConstants.SESSION_MAP.remove(session.getId());
    }

    /**
     * 监听 Session 属性添加
     *
     * @param event
     */
    @Override
    public void attributeAdded(HttpSessionBindingEvent event) {

        if (event.getName().equals(OnlineConstants.SESSION_PERSON)) {

            // 当前登录用户数++
            OnlineConstants.CURRENT_LOGIN_COUNT++;
            HttpSession session = event.getSession();

            // 查找该帐号有没有在其他机器上登录
            for (HttpSession oldSession : OnlineConstants.SESSION_MAP.values()) {

                // 如果该帐号已经在其他机器上登录，则以前的登录失效
                if (event.getValue().equals(oldSession.getAttribute(OnlineConstants.SESSION_PERSON))
                        && session.getId() != oldSession.getId()) {
                    oldSession.invalidate();
                }
            }
        }
    }

    /**
     * 监听 Session 属性删除
     *
     * @param event
     */
    @Override
    public void attributeRemoved(HttpSessionBindingEvent event) {

        // 注销 当前登录用户数--
        if (event.getName().equals(OnlineConstants.SESSION_PERSON)) {
            OnlineConstants.CURRENT_LOGIN_COUNT--;
        }
    }

    /**
     * 监听 Session 属性修改
     *
     * @param event
     */
    @Override
    public void attributeReplaced(HttpSessionBindingEvent event) {

        // 重新登录
        if (event.getName().equals(OnlineConstants.SESSION_PERSON)) {
            HttpSession session = event.getSession();
            for (HttpSession sess : OnlineConstants.SESSION_MAP.values()) {
                // 如果新帐号在其他机器上登录过，则以前登录失效
                if (event.getValue().equals(sess.getAttribute("personInfo"))
                        && session.getId() != sess.getId()) {
                    sess.invalidate();
                }
            }
        }
    }

}
